#ifndef GAMEENGINE_GRAPHICS_OPENGL_H
#define GAMEENGINE_GRAPHICS_OPENGL_H

#include <GL/glew.h>

#include <GameEngine/Graphics/graphics_settings.h>

#include <GameEngine/Core/string.h>


#ifdef GAMEENGINE_NAMESPACES
namespace GameEngine {
#endif

//! Small util class used to convert an OpenGL error code into its corresponding string
class _Graphics_decl GLError {

public:
	//! Convert an OpenGL error code into its corresponding string
	/*!
	 @param error The OpenGL error code
	 @return The CString which corresponds to the error code, if any
	 @note Valid error codes are GL_NO_ERROR, GL_INVALID_ENUM, GL_INVALID_VALUE,
	       GL_INVALID_OPERATION, GL_STACK_OVERFLOW, GL_STACK_UNDERFLOW,
		   GL_OUT_OF_MEMORY and GL_TABLE_TOO_LARGE
	 */
	static GEString gl_error(GLenum error) {
		if ( error == GL_NO_ERROR )				return "GL_NO_ERROR";
		if ( error == GL_INVALID_ENUM )			return "GL_INVALID_ENUM";
		if ( error == GL_INVALID_VALUE )		return "GL_INVALID_VALUE";
		if ( error == GL_INVALID_OPERATION )	return "GL_INVALID_OPERATION";
		if ( error == GL_STACK_OVERFLOW )		return "GL_STACK_OVERFLOW";
		if ( error == GL_STACK_UNDERFLOW )		return "GL_STACK_UNDERFLOW";
		if ( error == GL_OUT_OF_MEMORY )		return "GL_OUT_OF_MEMORY";
		if ( error == GL_TABLE_TOO_LARGE )		return "GL_TABLE_TOO_LARGE";
		return "UNKNOWN ERROR";
	}
};

//! Check whether an OpenGL error occurred so far, and display the result only if there was an error
/*!
 @note For the sake of efficiency, this only works in debug mode
 */
#ifndef _DEBUG
	#define CHECK_GL_ERRORS {}
#else
	#define CHECK_GL_ERRORS { \
		GLenum err = glGetError(); \
		if ( err ) \
			std::cout << "Error " << GLError::gl_error(err) << " at line " << __LINE__ << " in file " << __FILE__ << "." << std::endl; \
	}
#endif

//! Check whether an OpenGL error occurred so far, and display the result whether there was an error or not
/*!
 @note For the sake of efficiency, this only works in debug mode
 */
#ifndef _DEBUG
	#define CHECK_GL_ERRORS_INFO {}
#else
	#define CHECK_GL_ERRORS_INFO { \
		GLenum err = glGetError(); \
		if ( err ) \
			std::cout << "Error " << GLError::gl_error(err) << " at line " << __LINE__ << " in file " << __FILE__ << "." << std::endl; \
		else \
			std::cout << "No OpenGL error at line " << __LINE__ << " in file " << __FILE__ << "." << std::endl; \
	}
#endif

//! Clean the OpenGL error buffer
/*!
 @note For the sake of efficiency, this only works in debug mode
 */
#ifndef _DEBUG
	#define CLEAN_GL_ERRORS {}
#else
	#define CLEAN_GL_ERRORS { \
		GLenum err = glGetError(); }
#endif

#ifdef GAMEENGINE_NAMESPACES
} // namespace GameEngine
#endif

#endif

